import { getLogger } from '@gnlab/utils'
import type { OptionalFields } from '@gnlab/utils'
import { makeHTTPSAvatar } from '@/lib/https'
import { API } from '@/services/common/api'
import { type Word, formatIrregularWord } from '@/services/common/definition'
import { makeContactId, splitContactId } from '@/services/contacts'
import { formatChatFlowTaskTime } from './definition'
import type {
  ChatFlow,
  ChatFlowTask,
  BoundChatFlow,
  ChatFlowContact,
  ChatFlowApplyRecord,
} from './definition'

const logger = getLogger('services/features/chat-flows')

interface RawChatFlowTask {
  Day: number
  Time: string // '09:00'
  Content: Word[]
}
function formatRawChatFlowTask(raw: RawChatFlowTask): ChatFlowTask {
  const [rawHour, rawMinute] = raw.Time.split(':', 2)
  return {
    day: raw.Day,
    hour: parseInt(rawHour!, 10),
    minute: parseInt(rawMinute!, 10),
    words: raw.Content.map(formatIrregularWord),
  }
}
function makeRawChatFlowTask(item: ChatFlowTask): RawChatFlowTask {
  return {
    Day: item.day,
    Time: formatChatFlowTaskTime(item),
    Content: item.words,
  }
}

/**
 * 获取工作流列表
 */
interface RawChatFlow {
  Id: number
  Name: string
  Type: 0 | 1
  UnsubscribeText: string
  WorkflowContent: string
}
function formatRawChatFlow(raw: RawChatFlow): ChatFlow {
  let rawTasks: RawChatFlowTask[]
  try {
    rawTasks = JSON.parse(raw.WorkflowContent) as RawChatFlowTask[]
  } catch (e) {
    rawTasks = []
    logger.warn('解析工作流任务失败', raw)
  }
  return {
    id: raw.Id,
    name: raw.Name,
    forGroup: raw.Type === 1,
    unsubscribeKeyword: raw.UnsubscribeText,
    tasks: rawTasks.map(formatRawChatFlowTask),
  }
}
export async function getChatFlows() {
  return API('/ChatWorkflow/GetChatWorkflows', {
    formatter(data: RawChatFlow[]) {
      return data.map(formatRawChatFlow)
    },
  })
}

/**
 * 新增或修改工作流
 */
export async function addOrUpdateChatFlow(flow: OptionalFields<ChatFlow, 'id'>) {
  return API('/ChatWorkflow/SaveChatWorkflow', {
    data: {
      id: flow.id,
      name: flow.name,
      Type: flow.forGroup ? 1 : 0,
      UnsubscribeText: flow.unsubscribeKeyword,
      workflowContent: JSON.stringify(flow.tasks.map(makeRawChatFlowTask)),
    },
  })
}

/**
 * 删除工作流
 */
export async function removeChatFlow(id: number) {
  return API('/ChatWorkflow/RemoveChatWorkflow', {
    data: { id },
  })
}

/**
 * 获取绑定了指定工作流的客户列表
 */
interface RawChatFlowContact {
  WxId: string
  WxUserName: string
  WxNickName: string
  ContactUserId: string
  ContactName: string
  Avatar: string | null
  Status: 0 | 1 | 2 // 0 执行中，1 执行完成，2 已退订
}
function formatRawChatFlowContact(raw: RawChatFlowContact): ChatFlowContact {
  return {
    contactId: makeContactId(raw.WxId, raw.ContactUserId),
    ownerWxid: raw.WxId,
    ownerUsername: raw.WxUserName,
    ownerNickname: raw.WxNickName,
    userId: raw.ContactUserId,
    name: raw.ContactName,
    avatar: makeHTTPSAvatar(raw.Avatar ?? ''),
    status: raw.Status,
  }
}
export async function getChatFlowContacts(id: number) {
  return API('/ChatWorkflow/GetChatWorkflowContacts', {
    data: { workflowId: id },
    formatter(data: RawChatFlowContact[]) {
      return data.map(formatRawChatFlowContact)
    },
  })
}

/**
 * 获取指定客户应用了的工作流
 */
interface RawBoundChatFlow {
  WorkflowName: string
  Status: 0 | 1 | 2 // 0 执行中，1 已完成，2 已退订
}
function formatRawBoundChatFlow(raw: RawBoundChatFlow): BoundChatFlow {
  return {
    name: raw.WorkflowName,
    status: raw.Status,
  }
}
export async function getBoundChatFlow(contactId: string) {
  const [ownerWxid, contactUserId] = splitContactId(contactId)
  return API('/ChatWorkflow/GetChatWorkflowContact', {
    data: {
      wxid: ownerWxid,
      contactUserId,
    },
    formatter(raw: RawBoundChatFlow | null) {
      return raw ? formatRawBoundChatFlow(raw) : null
    },
  })
}

/**
 * 为客户应用工作流
 */
export async function bindChatFlow(contactId: string, chatFlowId: number) {
  const [ownerWxid, contactUserId] = splitContactId(contactId)
  return API('/ChatWorkflow/AddChatWorkflowContact', {
    data: {
      wxid: ownerWxid,
      contactUserId,
      workflowId: chatFlowId,
    },
  })
}

/**
 * 解除客户应用的工作流
 */
export async function unbindChatFlow(contactId: string) {
  const [ownerWxid, contactUserId] = splitContactId(contactId)
  return API('/ChatWorkflow/RemoveChatWorkflowContact', {
    data: {
      wxid: ownerWxid,
      contactUserId,
    },
  })
}

/**
 * 获取客户绑定的工作流的执行记录
 */
interface RawChatFlowApplyRecord {
  Day: number
  Time: string
  CreateTime: string // 发送时间或预计发送时间
  Content: Word[] // 发送内容
  State: 0 | 1 | 2 // 0 待执行，1 已执行，2 因用户退订而终止
}
function formatRawChatFlowApplyRecord(raw: RawChatFlowApplyRecord): ChatFlowApplyRecord {
  const [rawHour, rawMinute] = raw.Time.split(':', 2)
  return {
    day: raw.Day,
    hour: parseInt(rawHour!, 10),
    minute: parseInt(rawMinute!, 10),
    sendTime: raw.CreateTime,
    words: raw.Content,
    status: raw.State,
  }
}
export async function getChatFlowApplyRecords(contactId: string) {
  const [ownerWxid, contactUserId] = splitContactId(contactId)
  return API('/ChatWorkflow/GetChatWorkflowRecords', {
    data: {
      wxid: ownerWxid,
      contactUserId,
    },
    formatter(data: RawChatFlowApplyRecord[]) {
      return data.map(formatRawChatFlowApplyRecord)
    },
  })
}
